﻿Imports System.Reflection
Imports System.Reflection.Emit
Imports VBParser
Imports System.Collections.ObjectModel

Namespace Compiler.Semantic

    Public MustInherit Class TypeResolver
        Private m_nameSyntaxNode As TypeName
        Private m_resultSet As List(Of TypeReference)
        Private m_context As ResolveContext

        Protected Sub New(ByVal name As TypeName, ByVal context As ResolveContext)
            Debug.Assert(name IsNot Nothing AndAlso context IsNot Nothing)

            m_resultSet = New List(Of TypeReference)
            m_context = context
            m_nameSyntaxNode = name
        End Sub

        Public ReadOnly Property ResultSet() As ReadOnlyCollection(Of TypeReference)
            Get
                Return New ReadOnlyCollection(Of TypeReference)(m_resultSet)
            End Get
        End Property

        Protected ReadOnly Property Context() As ResolveContext
            Get
                Return m_context
            End Get
        End Property

        Protected ReadOnly Property TypeName() As TypeName
            Get
                Return m_nameSyntaxNode
            End Get
        End Property

        Protected Sub AddResult(ByVal result As TypeReference)
            m_resultSet.Add(result)
        End Sub

        Public Shared Function Create(ByVal name As TypeName, ByVal context As ResolveContext) As TypeResolver
            Debug.Assert(name IsNot Nothing)

            Select Case name.Type
                Case TreeType.IntrinsicType
                    Return New IntrinsicTypeResolver(TryCast(name, IntrinsicTypeName), context)
                Case TreeType.NamedType
                    Return New NamedTypeResolver(TryCast(name, NamedTypeName), context)
                Case TreeType.ArrayType
                    'TODO
            End Select

            Throw New ArgumentOutOfRangeException("name", "This name doesn't represent a type")
        End Function
    End Class

    Public Enum ResolveLevel
        TypeLevel
        CodeLevel
        GetTypeExp
    End Enum

    ''' <summary>
    ''' The resolve context contains file environment (imports), compile unit, current namespace/type
    ''' </summary>
    ''' <remarks></remarks>
    Public NotInheritable Class ResolveContext

        Private m_compileUnit As CompileUnitDescription
        Public ReadOnly Property CompileUnit() As CompileUnitDescription
            Get
                Return m_compileUnit
            End Get
        End Property

        Private m_currentContainer As NameContainer
        Public ReadOnly Property CurrentContainer() As NameContainer
            Get
                Return m_currentContainer
            End Get
        End Property

        Private m_level As ResolveLevel
        Public ReadOnly Property Level() As ResolveLevel
            Get
                Return m_level
            End Get
        End Property

        Public Sub New(ByVal compileUnit As CompileUnitDescription, ByVal currentContainer As NameContainer, ByVal stage As ResolveLevel)
            Debug.Assert(compileUnit IsNot Nothing AndAlso currentContainer IsNot Nothing)

            m_compileUnit = compileUnit
            m_currentContainer = currentContainer
            m_level = stage
        End Sub
    End Class
End Namespace

